#include "common.hpp"

#include <thread>
#include <mutex>
#include <condition_variable>

using namespace std;

class Source
{
public:
    void Produce()
    {
        for (int i = 0; i < 100; i++)
        {
            cout << "insert " << i << endl;
            unique_lock<mutex> guard(mtx_);
            queue_.push_back(i);
            cond_.notify_one();
        }
    }

    void Comsume()
    {
        int data = 0;
        while (true)
        {
            unique_lock<mutex> guard(mtx_);
            auto call = [&]() -> bool
            {
                if (!queue_.empty())
                    return true;
                return false;
            };
            // call返回true则不阻塞，返回false阻塞
            cond_.wait(guard, call);
            data = queue_.front();
            queue_.pop_front();
            mtx_.unlock(); // 提前解锁
            cout << "consume " << data << endl;
        }
    }

private:
    mutex mtx_;
    list<int> queue_;
    std::condition_variable cond_;
};

int main()
{
    Source src;
    thread thd1(&Source::Produce, &src);
    thread thd2(&Source::Comsume, &src);
    thd1.join();
    thd2.join();
    return 0;
}
